﻿#include <QTcpSocket>
#include "RecognizeDevice.h"
#include "../mainwindow.h"
#include "../task/onnxrecognizetask.h"
#include "../signal/mysignal.h"
#include <QThreadPool>

RecognizeDevice::RecognizeDevice(QObject *parent)
    : Device{parent}
    , m_pDescription((Description*)parent)
    , m_bUseGPU(false)
{

}

Device* RecognizeDevice::clone(Device* pDevice){
    m_strID = pDevice->getStrID();

    m_bUseGPU = ((RecognizeDevice*)pDevice)->GetUseGPU();
    m_strModelPath = ((RecognizeDevice*)pDevice)->GetModelPath();
    m_pDescription = ((RecognizeDevice*)pDevice)->GetDescription();
    return this;
}

RecognizeDevice::~RecognizeDevice(){
    uninitDevice();
}

int RecognizeDevice::initDevice() {
     return 0;
}

void RecognizeDevice::uninitDevice() {
}


QString RecognizeDevice::getClassName()
{
    return this->metaObject()->className();
}

void RecognizeDevice::writeXML(QXmlStreamWriter &writer)
{
    // 写入当前操作的信息
    writer.writeStartElement("RecognizeDevice");
    writer.writeAttribute(QStringLiteral("id"), m_strID);
    writer.writeTextElement("ModelPath",m_strModelPath);
    writer.writeTextElement("UseGPU",m_bUseGPU ? "true" : "false");
    writer.writeEndElement(); // 结束当前操作的元素
}

void RecognizeDevice::readFromXML(QXmlStreamReader &reader)
{
    QXmlStreamAttributes attributes = reader.attributes();
    if (attributes.hasAttribute("id")) {
        m_strID = attributes.value("id").toString();
    }

    QXmlStreamReader::TokenType token = reader.readNext();
    while (!(reader.tokenType() == QXmlStreamReader::EndElement
             && reader.name() == QStringLiteral("RecognizeDevice"))) {

        if (reader.name() == QStringLiteral("UseGPU")) {
            m_bUseGPU = false;
            QString value = reader.readElementText();
            m_bUseGPU = (value == "true");

            m_objDefectRecognizer.SetUseGPU(m_bUseGPU);
            //(2)
            //m_objORTRecognizer.LoadYoloModel();
        }else if(reader.name() == QStringLiteral("ModelPath")){
            QString value = reader.readElementText();
            SetModePath(value);
            m_objDefectRecognizer.SetYoloOnnxModelPath(value);

            m_objDefectRecognizer.LoadYoloModel();
        }

        reader.readNext();
    }
}
#ifdef MULTITHREAD_ONNX
void RecognizeDevice::writeData(const QVariant &data) {
    QMap<QString,QVariant> map = data.toMap();
    int imageNum = ((QVariant)map["content"]).toInt();
    char* pSrcBuffer = MainWindow::instance()->GetImageSrcBuffer(imageNum);
    map.insert("pSrcBuffer",        QVariant::fromValue((void *) pSrcBuffer));
    char* pDestBuffer = MainWindow::instance()->GetImageDestBuffer(imageNum);
    map.insert("pDestBuffer",        QVariant::fromValue((void *) pDestBuffer));
    map.insert("imageHeight",       IMAGE_HEIGHT);
    map.insert("imageWidth",        IMAGE_WIDTH);
    map.insert("imageChannel",      3);
    map.insert("pDefectRecognizer", QVariant::fromValue((void *) &m_objDefectRecognizer));
    CameraViewWidget* pViewWidget = MainWindow::instance()->GetImageCameraViewWidget(imageNum);
    map.insert("pViewWidget",       QVariant::fromValue((void *) pViewWidget));

    OnnxRecognizeTask* pTask = new OnnxRecognizeTask();
    pTask->SetParameters(map);
    QThreadPool::globalInstance()->start(pTask);

    connect(pTask,&OnnxRecognizeTask::finishRecognizeImage,MainWindow::instance(),&MainWindow::on_finishRecognizeImage_signal);
}
#else
void RecognizeDevice::writeData(const QVariant &data) {
    QMap<QString,QVariant> map = data.toMap();
    int imageNum = ((QVariant)map["content"]).toInt();
    qDebug() << "RecognizeDevice content = " << imageNum;


    char* pSrcBuffer = MainWindow::instance()->GetImageSrcBuffer(imageNum);

    cv::Mat imageSrc(IMAGE_HEIGHT,IMAGE_WIDTH,CV_8UC3);
    memcpy(imageSrc.data,pSrcBuffer,IMAGE_WIDTH * IMAGE_HEIGHT * 3);
    cv::Mat imageDst = imageSrc.clone();

    qint64 CurrentMEpoch1 = QDateTime::currentMSecsSinceEpoch();
    //m_objORTRecognizer.test(imageSrc);
    //std::vector<Detection> results = m_objORTRecognizer.RecognizePartsDefect(imageSrc);
    std::vector<Detection> results = m_objDefectRecognizer.RecognizePartsDefect(imageSrc);

    //m_objDefectRecognizer.test();

    m_objDefectRecognizer.DrawPred(imageDst, results);

    QString filename = QString("d:/test/seat/seat_yolov8n_%1.jpg").arg(imageNum);
    imwrite(filename.toStdString(), imageDst);

    char* pDestBuffer = MainWindow::instance()->GetImageDestBuffer(imageNum);
    memcpy(pDestBuffer,imageDst.data,IMAGE_WIDTH * IMAGE_HEIGHT * 3);

    qint64 CurrentMEpoch2 = QDateTime::currentMSecsSinceEpoch();
    QString elapse = QString::number(CurrentMEpoch2 - CurrentMEpoch1);
    qDebug() << elapse << "ms";
}
#endif
